﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Xml;
using System.Text;

using Wicresoft.SMS.Data;
using Wicresoft.SMS.Common;
using System.Configuration;



namespace Wicresoft.SMS.OMSService
{

    public class OMSUser
    {
        private string telNo;

        public string TelNo
        {
            get { return telNo; }
            set { telNo = value; }
        }

        private string email;

        public string Email
        {
            get { return email; }
            set { email = value; }
        }


        public OMSUser(string tel, string mail)
        {
            this.telNo = tel;
            this.Email = mail;
        }

    }

    

    public interface IDataService
    {
        //if failed return null
        OMSUser AuthoriseUser(string username, string password);
        //return the result xml response
        string SendSMS(string username, string password, string content, string addressforSP);
        contactData GetContacts(string UserName, string Password);
        //set user's mobile phone
        //0: success
        //1: no user
        //2: innererror
        int SetUserMobilePhone(string email, string mobile);
        //sync
        void Sync(IEnumerable<reminderDataReminder> datas , string email);

        void WriteLog(DateTime dt, string product, string type, string msg, string user);

        string GetGetEmailByCSL(string cil);

        bool CheckEmail(string email);

        string GetMobileByCSL(string csl);

        string GetCILByCSL(string csl);

        bool AuthUser(string username, string pwd);

        string GetCSLByCIL(string cil);
    }

    internal class WebConfigProvider : IConnectStringProvider
    {

        #region IConnectStringProvider Members

        private string _connectionString;
        private string _HRconnectionString;
       

        public string ConnectionString
        {
            get{
                if (_connectionString == null){
                    try{
                        _connectionString = ConfigurationManager.ConnectionStrings["smsConnector"].ConnectionString;
                    }
                    catch (Exception ex){
                        Logger.Error(ex.Message);
                    }
                }
                return _connectionString;
            }
        }

        public string HRConnectionString
        {
            get
            {
                if (_connectionString == null)
                {
                    try
                    {
                        _connectionString = ConfigurationManager.ConnectionStrings["smsConnector"].ConnectionString;
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex.Message);
                    }
                }
                return _connectionString;
            }
        }
        #endregion

        private string _CILServer;
        private string _AllowDebugLog;

        public string CILServer
        {
            get
            {
                if (_CILServer == null)
                {
                    try
                    {
                        _CILServer = ConfigurationManager.AppSettings["CILServer"].ToString();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex.Message);
                    }
                }
                return _CILServer;
            }
        }

        public string AllowDebugLog
        {
            get
            {
                if (_AllowDebugLog == null)
                {
                    try
                    {
                        _AllowDebugLog = ConfigurationManager.AppSettings["AllowDebugLog"].ToString();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex.Message);
                    }
                }
                return _AllowDebugLog;
            }
        }
      
    }

    internal enum SendResult { success , invaliduser , invalidtarget , monthlimit , innererror }


    public class DataService : IDataService
    {
        private static WebConfigProvider connectProvider;
        private static IUserRoleService userService;
        private static IPushMessageProvider pushService;
        private static ICommonService commonService;
        private static ReminderService reminderService;
        private static LogService logService;
        private static ICILHelper cilhelper;
        private const string m_sOmsNamespace = "http://schemas.microsoft.com/office/Outlook/2006/OMS";

        static DataService()
        {
            connectProvider = new WebConfigProvider();
            userService = new UserRoleService(connectProvider);
            pushService = DataProviderFactory.CreatePushMessageProvider(connectProvider);
            commonService = DataProviderFactory.CreateCommonService(connectProvider);
            reminderService = new ReminderService(connectProvider);
            logService = new LogService(connectProvider.ConnectionString);
            cilhelper = new CILHelper(connectProvider.CILServer, connectProvider.HRConnectionString);
        }

        public OMSUser AuthoriseUser(string username, string password)
        {
            if (userService == null)
                return null;
            if(!userService.ValidationUser(username,password))
                return null;
            var userinfo = userService.GetUserInfo(username);
            return new OMSUser(userinfo.Mobile, userinfo.Email);
        }
        public string SendSMS(string username, string password, string content, string addressforSP)
        {
            if (pushService == null)
                return BuildError("others", failed: true);
            Logger.Debug(string.Format("{0}、{1}、{2}、{3}",username, password, content, addressforSP));
            int result = pushService.SendSMS(username, password, content, addressforSP);
            switch ((SendResult)result)
            {
                case SendResult.success: return BuildError("ok", failed: false);
                case SendResult.invaliduser: return BuildError("invalidUser", failed: true);
                case SendResult.invalidtarget: return BuildError("invalidRecipient", failed: true);
                case SendResult.monthlimit: return BuildError("perMonthMsgLimit", failed: true);
                default: return BuildError("others", failed: true);
            }
        }

        
        public contactData GetContacts(string UserName, string Password)
        {
            IEnumerable<Contact> contacts = commonService.GetContacts(UserName, Password);
            if (contacts == null)
                return null;
            contactData data = new contactData();
            List<contactDataContact> returnContacts = new List<contactDataContact>();
            foreach (var c in contacts){
                if (!c.Enabled) continue;
                contactDataContact eachContact = new contactDataContact();
                eachContact.name = c.DisplayName;
                //now only the first number should be returned
                if (c.Number != null && c.Number.Count > 0)
                {
                    eachContact.numbers = c.Number.Select(p => p.Number1).ToArray();
                }
                else
                    continue;
                //TODO : templatly use now
                eachContact.lastmodifytime = DateTime.Now;
                returnContacts.Add(eachContact);
            }
            data.contact = returnContacts.ToArray();
            return data;
        }

        /// <summary>
        /// Simple helper method building the return XML for the SendXms method.
        /// </summary>
        /// <param name="errorCode">The error code.</param>
        /// <param name="failed">If this was a failure or not.</param>
        /// <returns>The XML fragment to return to the client.</returns>
        public static string BuildError(string errorCode, bool failed)
        {
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter wr = new XmlTextWriter(stringWriter);

            try
            {
                wr.WriteStartDocument();
                wr.WriteStartElement("xmsResponse", "http://schemas.microsoft.com/office/Outlook/2006/OMS");
                wr.WriteStartElement("error");
                wr.WriteAttributeString("code", errorCode);
                wr.WriteAttributeString("severity", failed ? "failure" : "neutral");
                wr.WriteEndElement();
                wr.WriteEndElement();
                wr.WriteEndDocument();
                return stringWriter.GetStringBuilder().ToString();
            }
            finally
            {
                wr.Close();
                stringWriter.Close();
            }
        }

        /// <summary>
        /// Simple helper method building the return XML for the GetUserInfo method.
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static string BuildUserRespose(OMSUser user)
        {
            StringWriter stringWriter = new StringWriter(new StringBuilder());
            XmlTextWriter wr = new XmlTextWriter(stringWriter);
            try
            {
                wr.WriteStartDocument();
                wr.WriteStartElement("userInfo", m_sOmsNamespace);
                wr.WriteStartElement("replyPhone");
                wr.WriteValue(user.TelNo ?? "");
                wr.WriteEndElement();
                wr.WriteStartElement("smtpAddress");
                wr.WriteValue(user.Email ?? "");
                wr.WriteEndElement();
                wr.WriteStartElement("error");
                wr.WriteAttributeString("code", "ok");
                wr.WriteEndElement();
                wr.WriteEndElement();
                wr.WriteEndDocument();
                return stringWriter.GetStringBuilder().ToString();
            }
            finally
            {
                wr.Close();
                stringWriter.Close();
            }

        }

        public int SetUserMobilePhone(string email, string mobile)
        {
            if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(mobile))
                return 1;
            return reminderService.SetUserMobilePhone(email, mobile);
        }

        public void Sync(IEnumerable<reminderDataReminder> datas, string email)
        {
            if (datas == null || string.IsNullOrEmpty(email)) return;
            reminderService.DeleteNoSendReminders(email);
            foreach (var r in datas){
                reminderService.InsertReminder(r.EntryID,
                    email,
                    r.Content,
                    r.ReminderTime,
                    r.StartTime,
                    r.EndTime
                    );
            }
        }



        public void WriteLog(DateTime dt, string product, string type, string msg, string user)
        {
            if (type.ToLower() == "debug" && connectProvider.AllowDebugLog.ToLower() != "true")
                return;
            logService.WriteLog(dt, product, type, msg, user);
        }


        public string GetGetEmailByCSL(string csl)
        {
            return userService.GetGetEmailByCSL(csl);
        }

        public bool CheckEmail(string email)
        {
            return userService.CheckEmail(email);
        }


        public string GetMobileByCSL(string csl)
        {
            return userService.GetMobileByCSL(csl);
        }


        public string GetCILByCSL(string csl)
        {
            return userService.GetCILByCSL(csl);
        }


        public bool AuthUser(string username, string pwd)
        {
            if (userService.AuthUser(username))
            {
                return cilhelper.ValidationUser(username, pwd);
            }
            else
                return false;
        }


        public string GetCSLByCIL(string cil)
        {
            return userService.GetCSLByCIL(cil);

        }
    }



}
